<?xml version='1.0' encoding='iso-8859-1'?>
<!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
	<head>
		<title>
			config.c
			</title>
		<meta http-equiv='content-type' content='text/html;iso-8859-1'/>
		<meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
		<meta name='author' content='cmaier@cmassoc.net'/>
		<meta name='robots' content='noindex,nofollow'/>
		<link href='toolkit.css' rel='stylesheet' type='text/css'/>
		</head>
	<body>
		<div class='headerlink'>
			[<a href='config2cfg.c.html' title=' config2cfg.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='Confirm.c.html' title=' Confirm.c '>NEXT</a>]
			</div>
<pre>
/*====================================================================*
 *
 *   Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or 
 *   without modification, are permitted (subject to the limitations 
 *   in the disclaimer below) provided that the following conditions 
 *   are met:
 *
 *   * Redistributions of source code must retain the above copyright 
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above 
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *
 *   * Neither the name of Qualcomm Atheros nor the names of 
 *     its contributors may be used to endorse or promote products 
 *     derived from this software without specific prior written 
 *     permission.
 *
 *   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE 
 *   GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE 
 *   COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR 
 *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 *   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 *--------------------------------------------------------------------*/

/*====================================================================*
 *
 *   config.c - configuration file reader;
 *
 *   configuration files contain named parts where each part may
 *   contain one of more named items that have text definitions;
 *
 *   the named file can be searched for the first occurance of a
 *   named part then the first occurance of a named item;
 *
 *   [part1]
 *   item1=text
 *   item2=text
 *
 *   [part2]
 *   item1=text
 *   item2=text
 *
 *--------------------------------------------------------------------*/

#ifndef CONFIG_SOURCE
#define CONFIG_SOURCE

/*====================================================================*
 *   system header files;
 *--------------------------------------------------------------------*/

#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;

/*====================================================================*
 *   custom header files;
 *--------------------------------------------------------------------*/

#include &quot;../tools/config.h&quot;
#include &quot;../tools/types.h&quot;
#include &quot;../tools/chars.h&quot;

/*====================================================================*
 *   program variables;
 *--------------------------------------------------------------------*/

static char buffer [1024] = &quot;&quot;;
static signed c;

/*====================================================================*
 *
 *   bool compare (FILE * fp, char const *sp);
 *
 *   compare file and text characters until they differ or until end
 *   of text, line or file occurs; a match is declared when the text
 *   ends before the line or file;
 *
 *   spaces and tabs within the argument string or file string are
 *   ignored such that &quot;item1&quot;, &quot; item1 &quot; and &quot;item 1&quot; all match;
 *
 *--------------------------------------------------------------------*/

static bool compare (FILE * fp, char const * sp)

{
	while (isblank (*sp))
	{
		sp++;
	}
	while ((*sp) &amp;&amp; (c != '\n') &amp;&amp; (c != EOF))
	{
		if (toupper (c) != toupper (*sp))
		{
			return (0);
		}
		do
		{
			sp++;
		}
		while (isblank (*sp));
		do
		{
			c = getc (fp);
		}
		while (isblank (c));
	}
	return (!*sp);
}

/*====================================================================*
 *
 *   void collect (FILE * fp);
 *
 *   collect text to end of line; remove leading and trailing space
 *   but preserve embedded space; replace selected escape sequences;
 *
 *--------------------------------------------------------------------*/

static void collect (FILE * fp)

{
	char *bp = buffer;
	char *cp = buffer;
	while ((c != ';') &amp;&amp; (c != '\n') &amp;&amp; (c != EOF))
	{
		if (c == '\\')
		{
			c = getc (fp);
			if (c == 'n')
			{
				c = '\n';
			}
			if (c == 't')
			{
				c = '\t';
			}
		}
		if ((cp - buffer) &lt; (signed)(sizeof (buffer) - 1))
		{
			*cp++ = c;
		}
		if (!isblank (c))
		{
			bp = cp;
		}
		c = getc (fp);
	}
	*bp = '\0';
	return;
}

/*====================================================================*
 *
 *   void discard (FILE * fp);
 *
 *   read and discard characters until end-of-line or end-of-file
 *   is detected; read the first character of next line if end of
 *   file has not been detected;
 *
 *--------------------------------------------------------------------*/

static void discard (FILE * fp)

{
	while ((c != '\n') &amp;&amp; (c != EOF))
	{
		c = getc (fp);
	}
	if (c != EOF)
	{
		c = getc (fp);
	}
	return;
}

/*====================================================================*
 *
 *   Const char * configstring (char const * file, char const * part, char const * item, char const * text)
 *
 *   open the named file, locate the named part and return the named
 *   item text, if present; return alternative text if the file part
 *   or item is missing; the calling function must preserve returned
 *   text because it may be over-written on successive calls;
 *
 *--------------------------------------------------------------------*/

char const * configstring (char const * file, char const * part, char const * item, char const * text)

{
	FILE *fp;
	if ((!file) || (!part) || (!item))
	{
		return (text);
	}
	if ((fp = fopen (file, &quot;rb&quot;)))
	{
		for (c = getc (fp); c != EOF; discard (fp))
		{
			while (isblank (c))
			{
				c = getc (fp);
			}
			if (c != '[')
			{
				continue;
			}
			do
			{
				c = getc (fp);
			}
			while (isblank (c));
			if (!compare (fp, part))
			{
				continue;
			}
			if (c != ']')
			{
				continue;
			}
			for (discard (fp); (c != '[') &amp;&amp; (c != EOF); discard (fp))
			{
				while (isblank (c))
				{
					c = getc (fp);
				}
				if (c == ';')
				{
					continue;
				}
				if (!compare (fp, item))
				{
					continue;
				}
				if (c != '=')
				{
					continue;
				}
				do
				{
					c = getc (fp);
				}
				while (isblank (c));
				collect (fp);
				text = strdup (buffer);
				break;
			}
			break;
		}
		fclose (fp);
	}
	return (text);
}

/*====================================================================*
 *
 *   unsigned confignumber (char const * file, char const * part, char const * item, unsigned number)
 *
 *   open the named file, locate the named part and return the named
 *   item as an unsigned integer, if present; return a default number
 *   if the file, part or item is missing; 
 *
 *--------------------------------------------------------------------*/

unsigned confignumber (char const * file, char const * part, char const * item, unsigned number) 

{ 
	unsigned value = 0; 
	char const * string = configstring (file, part, item, &quot;&quot;); 
	if ((string) &amp;&amp; (* string)) 
	{ 
		while (isdigit (* string)) 
		{ 
			value *= 10; 
			value += * string++ - '0'; 
		} 
		if (! (* string)) 
		{ 
			number = value; 
		} 
	} 
	return (number); 
}

/*====================================================================*
 *
 *   unsigned confignumber_range (char const * file, char const * part, char const * item, unsigned number, unsigned min, unsigned max)
 *
 *   open the named file, locate the named part and return the named
 *   item as an unsigned integer, if present; return a default number
 *   if the file, part or item is missing or item is out of range; 
 *
 *--------------------------------------------------------------------*/

unsigned confignumber_range (char const * file, char const * part, char const * item, unsigned number, unsigned min, unsigned max)

{
	unsigned value = 0;
	char const * string = configstring (file, part, item, &quot;&quot;);
	if ((string) &amp;&amp; (* string))
	{
		while (isdigit (* string))
		{
			value *= 10;
			value += * string++ - '0';
		}
		if (! (* string))
		{
			if ((value &gt;= min) &amp;&amp; (value &lt;= max))
			{
			    number = value;
			}
		}
	}
	return (number);
} 

/*====================================================================*
 *
 *   int main (int argc, char const * argv []);
 *
 *   demo/test program; arguments are file, part, item and text in
 *   that order; you can construct your own configuration file and
 *   observe behaviour;
 *
 *--------------------------------------------------------------------*/

#if 0

#include &lt;stdio.h&gt;

int main (int argc, char const * argv [])

{
	char const * text = configstring (argv [1], argv [2], argv [3], argv [4]);
	printf (&quot;file=[%s] part=[%s] item=[%s] text=[%s]\n&quot;, argv [1], argv [2], argv [3], text);
	return (0);
}

#endif

/*====================================================================*
 *
 *--------------------------------------------------------------------*/

#endif


</pre>
		<div class='footerlink'>
			[<a href='config2cfg.c.html' title=' config2cfg.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='Confirm.c.html' title=' Confirm.c '>NEXT</a>]
			</div>
		</body>
	</html>
